package com.googlecode.lemyriapode.type;

import com.googlecode.lemyriapode.regle.Position;
import com.googlecode.lemyriapode.regle.Position.Piece;
import com.googlecode.lemyriapode.regle.Regle;
import com.googlecode.lemyriapode.type.AFRegle.IClosure;
import com.googlecode.lemyriapode.type.AFRegle.IPredicate;
import com.googlecode.lemyriapode.type.Echiquier.Case;
import com.googlecode.lemyriapode.type.Echiquier.Direction;

public abstract class AFPosition extends AF<Object, Position> {

    public IPredicate isACaseOut,  estUnePieceAJouer,  isLastDirection,  isDirectionAutoriser,  isMultiDeplacement;
    public IClosure explorerDirection,  rienFaire,  exploreDir,  exploreDir1Case;
    public Case _c;
    public Piece piece_c;
    public Direction dir;
    public Echiquier echq;
    public Regle regle;
    public Position pos;
    public int I;
    public int J;
    public boolean flag1Case;

    public AFPosition() {
        isLastDirection = new IPredicate() {

            public boolean eval() {
                return !(pos.echiquier.dir.ordinal() > 7);
            }
        };
        isACaseOut = new IPredicate() {

            public boolean eval() {
                return !pos.echiquier._c.equals(Case.out);

            }
        };
        estUnePieceAJouer = new IPredicate() {

            public boolean eval() {
                return (piece_c != null) && (piece_c.couleur && pos.trait);
            }
        };
        explorerDirection = new IClosure() {

            public void exec() {
                regle.fDir.f0(new Position(_c, echq.dir));
            }
        };
        rienFaire = new IClosure() {

            public void exec() {
            }
        };
        isDirectionAutoriser = new IPredicate() {

            public boolean eval() {
                return dir.estInclus(piece_c.Regle_Mouvt);
            }
        };
        exploreDir = new IClosure() {

            public void exec() {
                regle.fMDir.f1(new Position(_c, dir));
            }
        };
        exploreDir1Case = new IClosure() {

            public void exec() {
                regle.fMDir1.f1(new Position(_c, dir));
            }
        };
        isMultiDeplacement = new IPredicate() {

            public boolean eval() {
                return piece_c._NCase;
            }
        };
    }

    @Override
    public abstract boolean continuer(int n, Position e);

    @Override
    public abstract void executer(int n, Position e);

    @Override
    public abstract Object stopper(int n, Position e);

    public void SiSinon(IPredicate pred, IClosure trueclos, IClosure falseclos) {
        if (pred.eval()) {
            trueclos.exec();
        } else {
            falseclos.exec();
        }
    }

    public void _Case_Suivante() {
        echq._c = _c.next();
    }

    public void _Piece_En_C() {
        piece_c = regle.position.posCourante.get(_c);
    }

    public void _Case_C() {
        echq = pos.echiquier;
        _c = echq._c;
    }
}
